


	
springcloud 
1、服务发现注册 eureka
(nacos)

2、rebbon 客户端负载均衡
3、熔断限流hystrix
	* 服务降级: 返回fallback
	* 服务熔断: 返回自定义的返回方法
	* 服务隔离：隔离服务之间相互影响
	* 服务监控：在服务发生调用，将一些操作数据记录下来
4、feign调用

5、spring config注册中心

6、网关 zuul（getway）


锁
redis zset跳表、
线程池
hashMap原理 数组=》hash冲突时转化为链表》=》转化为红黑树


jvm类加载过程：
1、加载
	* 通过类的全限定名获取这个类的二进制字节流
	* 将这个字节流的静态存储结构转化为方法区的运行时数据结构，包括创建运行时常量池，将类常量池部分符号引用放入运行时常量池
	* 在内存中生成这个类的java.lang.Class对象，作为方法区这个类各种数据的访问入口
2、链接
	1、验证 
		验证文件是否符合jvm解析条件
	2、准备
		为类变量分配空间，并赋0值
	3、解析
		将方法区-运行时常量池中的符号引用转为直接引用
3、初始化
	为类变量显式赋值，执行静态代码块
	
判断对应类是否加载过：首先JVM检查在方法区Metaspace（元空间）的常量池里能否定位到该类的符号引用，能的话通过符号引用检查该类是否加载链接初始化过；若没有则在双亲委派机制下，当前类加载器调用findClass()方法查找类的.class字节码文件，然后调用loadClass("类全限定名")方法遵循双亲委派机制加载链接初始化类到内存中，并生成类的class对象，作为方法区这个类各种数据的访问入口。
创建对象：
分配堆内存空间：如果内存规整：（例如标记整理算法），采用指针碰撞法为新对象分配内存。如果内存不规整：（有内存碎片，例如标记清除算法），在空闲列表里找到合适大小的空闲内存分配给新对象。现在主流虚拟机新生代都是使用标记复制算法，内存都是规整的。
处理并发安全问题：CAS失败重试，区域加锁，每个线程分配一块TLAB内存缓冲区。
设置对象头：将哈希码、GC分代年龄、锁信息、GC标记等存在对象头的Mark Word中；
成员变量赋初值：若指定了初值则赋指定的值。若未指定初值，则基本类型赋0或false


HashMap的put方法的总结
判断table是否为空，如果空的话，会先调用resize扩容；
根据当前key的 hash 值，通过 (n - 1) & hash计算应当存放在数组中的下标 index ；
查看 table[index] 是否存在数据，没有数据就构造一个 Node 节点存放在 table[index] 中；
存在数据，说明发生了 hash 冲突，继续判断 key 是否相等，如果相等，用新的 value 替换原数据(这里onlyIfAbsent 为 false)；
如果不相等，判断当前节点类型是不是树型节点，如果是树型节点，创建树型节点插入红黑树中；
如果不是树型节点，则采用尾插法，把新节点加入到链表尾部；判断链表长度是否大于 8， 大于的话，再判断数组长度是否小于64，小于则扩容，大于则链表转换为红黑树；
插入完成之后判断当前节点数是否大于阈值，如果大于开始扩容为原数组的二倍。


redis
1、缓存击穿、缓存穿透、缓存雪崩 解决方案

	* 缓存击穿（热点key失效，大量用户访问）
		① 同雪崩
	* 缓存穿透（大量请求访问不存在的key）
		① 对空值进行缓存（设置value为空）
		② 对redis进行实时监控，把问题ip或请求拦截
		③ 使用布隆过滤器，将目前所有的数据映射到布隆过滤器中，当有个请求过来的时候，先通过布隆过滤器判断，有则放行，否则拦截
		④ 接口拦截，对不符合业务数据规范的请求进行拦截
	* 缓存雪崩（大范围key过期）
		① 预先热门词汇的设置，进行key时长调整
		② 实施调整，监控哪些数据是热门数据，实施调整key的过期时长
		③ 使用锁机制（redis查不到数据时，使用排它锁，其他线程等待）

压缩列表（ziplist） 是 Redis 为了节省内存而开发的，是由一系列特殊编码的连续内存块组成的顺序型数据结构，
一个压缩列表可以包含任意多个节点（entry），每个节点可以保存一个字节数组或者一个整数值。
**hash ziplist 和 hashtable 两种。当哈希对象保存的键值对数量小于 512 并且所有键值对的长度都小于 64 字节时，使用压缩列表存储；否则使用 hashtable 存储。
**list 列表对象的编码有 ziplist 和 linkedlist 两种。当列表的长度小于 512，并且所有元素的长度都小于 64 字节时，使用压缩列表存储，否则使用 linkedlist 存储。
**set 列表对象的编码有 intset 和 hashtable 两种。当集合的长度小于 512，并且所有元素都是整数时，使用整数集合存储；否则使用 hashtable 存储。
**sort set 有序集合对象的编码有 ziplist 和 skiplist 两种。当有序集合的长度小于 128，并且所有元素的长度都小于 64 字节时，
	使用压缩列表存储；否则使用 skiplist 存储。
为什么要用redis
	* redis是基于内存，没有磁盘IO的开销
	* 高效的存储结构{sds,hash,跳表,压缩链表}
	* 合理的线程模型{单线程模式，避免上下文切换 io多路复用（一个线程操作多个文件）}
	
			RDB		AOF
启动优先级	低		高
体积			小		大
恢复速度		快		慢
数据安全性	丢数据	取决于刷盘策略
轻重			重		轻
	
布隆过滤器可以应对缓存穿透问题

数据结构：一个很长的二进制向量和一组Hash映射函数组成。

作用：检索一个元素是否在一个集合中，空间查询效率比一般的算法要好的多。

缺点：有一定误识别率和删除困难。

原理：集合A中有n个元素，利用K个哈希散列函数，将A中每个元素映射到一个长度为a位的数组B中不同位置上。这些位置上的二进制数均设置为1。经过这个K个哈希散列函数映射后，发现其k个位置上的二进制数全部为1，这个元素很可能属于集合A。


联合索引
数据库传播级别：
	* 读未提交 一个事务可以读取另外一个事务未提交的数据  ---导致脏读、幻读、不可重复读问题
	* 读已提交（oracle默认隔离级别） 一个事务读取过程中，读取了别人已提交的数据，形成前后数据不一致 ---不可重复读问题 
	* 可重复读（mysql默认隔离级别） 解决不可重复读问题
	* 序列化 事务串行进行，安全性最高，但效率低下
	
mysql与oracle语法区别

				mysql															oracle
时间转字符串  	date_format(now(),'%Y-%m-%d') 									to_char(sysdate, 'YYYY-MM-DD')
字符串转时间		str_to_date('2020-02-01','%Y-%m-%d')							to_date('2020-02-01','YYYY-MM-DD')
条件函数			if(value=a,b,c)													decode(value,a,b,c)
trunc函数		truncate(12.21)=12	trunc(12.21)=12; 							trunc(12.332,3)=12.33	
格式转换			转化数字 cast('123' as signed);字符串 cast(123 as char(3))   		to_char(123) to_number('123')

EXPLAIN PLAN FOR
SELECT * FROM your_table WHERE your_column = 'some_value';

SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY);



锁：
互斥锁:线程加锁失败后，会把该线程设置sleep，线程释放cpu给其他线程，等线程释放锁后，再恢复操作
自旋锁（CAS）:加锁失败会一直等待，直到获取锁
读写锁:写独占，读共享。适合写操作少的时候
悲观锁:
乐观锁:默认没有发生冲突，等修改完成，如果期间数据已经被修改过，就放弃本次操作




mysql窗口函数之排序
1、row_number() 	去重排序 		1234567
2、rank() 			跳跃排序   		1133567
3、dense_rank() 	连续排序		1122345
-----start-----
 dense_rank() over(partition by 分组字段 order by 排序字段 desc) as '序号命名'
------end------



待办：布隆过滤器原理：
单例、多例、双重检查锁
单例使用场景：
1、读取配置文件，不可能每次new 对象，每次去读取文件，很影响性能
2、比如在不考虑分布式场景，使每个用户在相同时刻获取人数数量都是一致的
3、数据库连接池，包括线程池，减少新建连接，初始化的开销
实现方法：静态内部类（懒汉式），枚举方式





binlog row 记录每一行的数据 
statement 记录每一条修改语句 
mixed对于statement记录不了的采用row来记录

优化
1、写法上避免隐式转换
2、劲量默认设置初始值，避免is null和 is not null or <>使索引失效
3、适当创建联合索引，减少后期回表，，最左前缀原则，和b+树结构有关，索引排序方式:先按第一个进行排序，如果相等再第二个
4、避免在索引列做任何计算
5、范围查询后面的条件都会失效




ES（Elasticsearch）是一种基于Lucene库的开源、分布式、RESTful搜索引擎。它在全文搜索、结构化搜索、分析以及这三个领域的组合方面有着广泛的应用。以下是ES的主要使用场景：

日志和事件分析：Elasticsearch可以收集、存储和分析各种日志和事件数据，如系统日志、应用程序日志、安全事件等。通过强大的查询和分析功能，可以帮助用户快速定位和解决问题。
全文搜索：Elasticsearch提供了全文搜索功能，可以对大量的文本数据进行高效的索引和搜索。它可以处理各种语言，并支持复杂的查询语法，使得用户可以轻松地实现精确的搜索。
实时分析：Elasticsearch支持实时数据分析，可以对数据进行实时索引和查询。这使得用户可以及时获取最新的数据分析和统计结果，为决策提供有力的支持。
推荐系统：Elasticsearch可以通过基于内容的推荐算法，根据用户的历史行为和偏好，为用户推荐相关的内容或产品。这可以帮助提高用户体验和增加用户粘性。
安全智能：Elasticsearch可以与安全信息和事件管理（SIEM）工具集成，提供安全事件的实时分析和监控。通过监控网络流量、用户行为等安全事件数据，可以帮助用户及时发现并应对安全威胁。
电子商务：Elasticsearch在电子商务领域也有广泛的应用。它可以处理大量的商品信息、用户行为数据等，并提供高效的搜索和推荐功能。这可以帮助电商企业提高销售额和用户满意度。



　Apache Kafka是由Apache开发的一种发布订阅消息系统，它是一个分布式的、分区的和重复的日志服务。
高吞吐量、低延迟：kafka每秒可以处理几十万条消息，它的延迟最低只有几毫秒，每个topic可以分多个partition, consumer group 对partition进行consume操作。
•可扩展性：kafka集群支持热扩展
•持久性、可靠性：消息被持久化到本地磁盘，并且支持数据备份防止数据丢失
•容错性：允许集群中节点失败（若副本数量为n,则允许n-1个节点失败）
•高并发：支持数千个客户端同时读写

分区对于 Kafka 集群的好处是：实现负载均衡。分区对于消费者来说，可以提高并发度，提高效率。

​ Redis实现高可用，在于提供多个节点，通常有三种部署模式：主从模式，哨兵模式，集群模式。



spring bean生命周期
实例化
属性赋值
初始化
销毁 destory方法--实现BisposableBean接口







*** io多路复用：
一个线程监控多个文件句柄，当有文件句柄就绪时，通知线程进行读写操作。
三种方式实现：
select()
采用轮询遍历，每次调用需要将文件标识符（fd）集合从用户态拷贝到内核态，而且单个线程打开的fd是有限制的，默认1024个
poll()
跟select大致一样，主要区别就是fd数量无限制
epoll()
只能在linux系统下工作，用户态拷贝到内核态只需要一次，通过epoll_tcl函数注册fd，
一旦有fd就绪后，就会通过callback回调机制来激活对应fd，进行相关的io操作。
高性能得益于以下函数：
epoll_create()系统启动时，在linux内核中申请一个b+树结构文件系统，返回epoll对象，也就是一个fd
epoll_ctl()每新建一个连接，都通过该函数进行操作epoll对象，在这个对象里修改添加删除对应的连接fd，并绑定一个callback函数。
epoll_wait()轮询所有的call_back集合，完成对应的IO操作


5种IO模型：
1、堵塞IO模型
2、非堵塞IO模型
3、复用IO模型（select,poll,epoll)
4、信号驱动IO模型（异步非阻塞IO）
5、异步IO模型

** BIO（同步堵塞）
服务器采用单线程，只能处理一个操作，无法并发
服务器采用多线程，会增大线程开销，造成资源浪费

** NIO（同步非堵塞）
当服务端接受一个请求，加入fd集合，每次轮询一遍fd集合数据，没有则立即返回错误


spring容器初始化：
1、启动阶段
通过springDefinationReader读取配置信息，生成元信息类BeanDefination对象，并将其注册到BeanDefinationRegister对象中
BeanFactoryPostProcess将会对注册的BeanDefination对象进行最后的修改，替换占位符，完成真实数据的注入
2、获取bean阶段
如果配置了懒加载，则在获取该对象实例前，bean对象以beanDefination形式存储在BeanDefinationRegister内
先判断缓存或BeanFactory中是否存在bean对象，不存在则调用getBean获取



//https://blog.csdn.net/a745233700/article/details/113840727?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522171919383816800182136399%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fblog.%2522%257D&request_id=171919383816800182136399&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~blog~first_rank_ecpm_v1~hot_rank-5-113840727-null-null.nonecase&utm_term=springbean%E7%9A%84%E5%88%9B%E5%BB%BA%E8%BF%87%E7%A8%8B&spm=1018.2226.3001.4450

线程池：拒绝策略：
任务丢失，抛出运行时异常
什么都不做
执行
提出最先进入队列的任务
实现rejectedExecutionHandler接口，可自定义处理器

布隆过滤器：
**作用：
	检查一个元素是否在集合内
**优点：
*	增加和查询速度快，
*	保密性强，不存储元素本身；
*	存储空间小，节省空间
布隆过滤器由一个二进制数组和一系列hash函数组成。


敏感词 

root->赌->博
root->赌->场

构建前缀树TempNode 内部两个属性 敏感词结束标、Map<Character,TempNode>
遍历文本内容
判断是否为符号{
如果不是敏感词中间的符号，就追加到结果文本中
}
双指针检测 双指针刚开始在链表头位置，找到敏感词前缀，二指针移动，如果找到敏感词结束标志，一指针移动到二指针位置。
如果未找到敏感词位置，一指针向前移动一个位置，二指针回到一指针位置。然后再判断一指针当前是不是敏感词前缀。。。


除了从sql层面，怎么优化查询
系统层面上优化：
	【1】采用分布式架构：
				主从复制：
					当主库故障时，可以快速切换到从库提供服务
					分担主库负载，可以将请求分发到从库，减轻主库负担
				读写分离：
					主库负责写，从库负责读
					将读请求分发到从库中处理，减轻主库的负担
	【2】使用缓存：
			前端缓存：
				可以通过将数据存放在http缓存头中
			应用数据缓存：
				将数据缓存在应用内存中，可以使用一些框架实现，如redis
			数据库缓存：
				可以使用mysql内置缓存机制来实现，如query cache、innodb buffer pool等
	 【3】使用搜索引擎
			使用ES，需要考虑数据一致性问题
软件层面上：
	【1】调整innodb内存池大小 innodb_buffer_pool_size，正常设置大小在系统内存的50-70%
	【2】清理日志文件：mysql的错误日志，二进制日志，慢查询日志等日志文件肯可能会占用大量存储空间
	【3】清理未使用的表和索引，占用存储空间
	【4】清理无用的备份文件，保留最新的有效文件
	【5】优化存储方式，可以适当更改存储引擎
	【6】创建适量索引
	【7】配置最大连接数max_connections，正常来说最大连接数应该要大于服务器并发连接数
	【8】分库分表：
			垂直分库：将大型的数据库拆分为多个小数据库，每个库中包含一部分表，缺点：数据一致性
			水平分库：将大型数据库的表按某种规则分散到多个小数据库中，一个小数据库包含一部分表，缺点：数据一致性
			水平分表：将大数据表，比如按id范围分到不同的表中。缺点是可能导致查询水平下降
	





jvm底层模型jvm调优参数：
Xmn 年轻代大小
Xmx	堆最大大小
Xms 堆初始大小
Xss 栈大小
newRatio 年轻代：老年代
survivorRatio eden:survivor
MaxTenuringThreshold=15 设置垃圾最大年龄

类加载子系统：
运行时数据区：
	虚拟机栈：
		局部变量表
		动态链接：方法外部引用
		操作数栈：操作
		方法返回地址
	本地方法栈：存放本地方法，用c语言实现
	方法区：存放类变量信息
	堆：存放对象
	程序计数器：存放下一个指令的地址
执行引擎：执行字节码

CMS的垃圾回收原理
标记清除算法：
		1、标记GC-ROOT直接引用，会stw，时间很短
		2、并发标记 以直接应用，并发标记所有关联对象
		3、重复标记，校正可达状态
		4、并发清楚不可达对象

mybatis分布式锁


hashMap put操作
初始化为长度16的数组，先通过hash寻址，计算桶的位置，如果第一个的元素的key与当前key相等，则直接替换。
如果该元素类别是否为红黑树，是的话，执行红黑树逻辑，进行相应左旋右旋。
否则就是链表，遍历链表，如果key相同则替换value，不同则在链表底部新增节点，当节点长度大于8时，转换为红黑树
再判断size是否大于阈值 大于的话，进行扩容处理	


数组+链表
将key通过hash计算，得到hashCode，对数组长度取膜，得到数组的索引下表。
1.8对hash算法做了优化：
将hashCode（int值，32位）二进制右移16位和原code进行异或运算（相同为1，不同为0），
使hashCode低16位同时具有高16位和低16位的特征，尽量避免hash冲突---》后续寻址算法会计算位置


寻址算法优化：
与运算替代取模，提升性能。
hash对n取模效果 == hash & (n-1)  与运算（相同为0 不同为1） n为数组长度，为2的m次方

hashMap解决hash冲突：
当计算的hashCode相同时，将放置到同一数组下表内，get的时间复杂度为O(n)
当长度达到一定长度时，链表转化为红黑树O(lognN)

可达性分析算法：
以GC-ROOT为根节点，向下查找，对直接或间接引用的对象头上标记可达
标记完，对不可达对象判断是否有必要执行finalize方法，并放入F-Queue队列中，过段时间会执行finalize方法。如果执行完未有引用关系，则会被垃圾回收


spring bean的创建流程：
加载bean信息
1、实例化bean
	createBeanInstance
2、设置属性值
3、调用对应的aware方法
4、BeanPostProcess前置处理
5、initialingBean处理
6、init-method处理
7、BeanPostProcess后置处理

autowire的底层实现


三级缓存 
一级缓存singletonObjects，存放完全初始化好的bean
二级缓存earlySingletonObjects已经创建但是尚未完全初始化（如属性填充和初始化方法的调用）
三级缓存singletonFactorys 存放bean的工厂对象
为什么不能用二级缓存
此时B相当于从三级缓存中拿到了A的代理对象，B为了后面的C和自己拿到的是同一个A的代理对象，
他就需要把这个A代理对象放入第二级缓存。同时移除第三级缓存的A，表示A已经提前创建好了代理对象，不需要再从三级缓存里面获取新代理对象了。
接下来，B的创建好后，A继续注入C，C直接从第二级拿到已经创建好了的A的代理对象。A在后面的初始化阶段执行
@Nullable
	protected Object getSingleton(String beanName, boolean allowEarlyReference) {
		// Quick check for existing instance without full singleton lock
		Object singletonObject = this.singletonObjects.get(beanName);
		if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
			singletonObject = this.earlySingletonObjects.get(beanName);
			if (singletonObject == null && allowEarlyReference) {
				synchronized (this.singletonObjects) {
					// Consistent creation of early reference within full singleton lock
					singletonObject = this.singletonObjects.get(beanName);
					if (singletonObject == null) {
						singletonObject = this.earlySingletonObjects.get(beanName);
						if (singletonObject == null) {
							ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
							if (singletonFactory != null) {
								singletonObject = singletonFactory.getObject();
								this.earlySingletonObjects.put(beanName, singletonObject);
								this.singletonFactories.remove(beanName);
							}
						}
					}
				}
			}
		}
		return singletonObject;
	}




spring bean创建过程
1、加载bean信息
	将扫描到的类形成beanDefinition对象，存放bean的一些属性特征，如bean名称、路径、是否单例等信息
	通过beanDefinitonRegister加载beanDefinition信息
2、实例化bean 
	通过尝试 getBean=》doGetBean=》getSingleton 去获取bean，如果获取不到再启动创建过程
3、填充属性
	popuateBean(beanName,beanDefination)，根据beanDefination判断是按名称注入还是按类型，并调用getSingleton获取所需对象去获取对应单例。
	通过autoware内置处理器调用postProcessProperties注入属性
4、初始化对象
	判断有无实现aware接口，获取容器所有的postProcess接口，执行前置方法
4、后置操作
	清理三级缓存，二级缓存中无用的bean引用。将bean添加到单例池


mysql存储过程 innodb\mysam
区别：innodb支持事务,mysam不支持


bean销毁是实现disposeBean接口，重写destory方法

threadlocal使用场景及原理
线程内部维护了一个threadlocalMap变量
而threadLocalMap 由entry数组组成，entry对象内部包含了threadlocal对象和其泛型值。 entry类实现了弱引用
get的时候通过hash寻址计算key位置，获取对应的entry对象，返回其value

为什么要用弱引用：
如果ThreadLocal变量被手动设置为null时，此时只有Entry有对ThreadLocal的弱引用，
那么当系统GC时就会回收ThreadLocal弱引用，value在下次调用ThreadLocal的set,get，remove方法的时，
因为key为null，所以会被清除。如果是强引用，那么Entry对ThreadLocal不会回收，那么obiect不会被清除。


**mysql读已提交和可重复度 mvcc的实现区别
MySQL实现MVCC机制的方式: undo log多版本链+ReadView机制
读已提交在一次事务中，每次查询，会生成一个readView
而可重复读，只会在第一个select时生成一个readView
